package com.yanqu.road.factory;

import com.yanqu.road.define.YanQuWSDefine;
import com.yanqu.road.ns0.YanQuWSH0;
import com.yanqu.road.hs7.YanQuWSH7;
import com.yanqu.road.fs8.YanQuWSH8;
import com.yanqu.road.ak13.YanQuWSH13;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpHeaders.Names;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

/**
 * websocket工厂
 */
public class YanQuWSHFactory {

	private static final InternalLogger logger = InternalLoggerFactory.getInstance(YanQuWSHFactory.class);

	private final String webSocketURL;

	private final String subprotocols;

	private final boolean allowExtensions;

	private final int maxFramePayloadLength;

	/**
	 * @deprecated use {@link #sendUnsupportedVersionResponse(Channel)}
	 */
	@Deprecated
	public static void sendUnsupportedWebSocketVersionResponse(Channel channel) {
		sendUnsupportedVersionResponse(channel);
	}

	/**
	 * Return that we need cannot not support the web session version
	 */
	public static ChannelFuture sendUnsupportedVersionResponse(Channel channel) {
		return sendUnsupportedVersionResponse(channel, channel.newPromise());
	}

	/**
	 * Return that we need cannot not support the web session version
	 */
	public static ChannelFuture sendUnsupportedVersionResponse(Channel channel, ChannelPromise promise) {
		HttpResponse res = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.UPGRADE_REQUIRED);
		res.headers().set(Names.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue());
		HttpHeaders.setContentLength(res, 0);
		return channel.writeAndFlush(res, promise);
	}

	public YanQuWSHFactory(String webSocketURL, String subprotocols, boolean allowExtensions) {
		this(webSocketURL, subprotocols, allowExtensions, YanQuWSDefine.MAX_FRAME_PAYLOAD);
	}

	public YanQuWSHFactory(String webSocketURL, String subprotocols, boolean allowExtensions,
						   int maxFramePayloadLength) {
		this.webSocketURL = webSocketURL;
		this.subprotocols = subprotocols;
		this.allowExtensions = allowExtensions;
		this.maxFramePayloadLength = maxFramePayloadLength;
	}

	public WebSocketServerHandshaker getHandshaker(HttpRequest req) {
		String version = req.headers().get(Names.SEC_WEBSOCKET_VERSION);
		if (version != null) {
			if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) {
				return new YanQuWSH13(version, version, allowExtensions, maxFramePayloadLength);
			} else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) {
				return new YanQuWSH8(version, version, allowExtensions, maxFramePayloadLength);
			} else if (version.equals(WebSocketVersion.V07.toHttpHeaderValue())) {
				return new YanQuWSH7(version, version, allowExtensions, maxFramePayloadLength);
			} else {
				logger.error("handshaker not find");
				return null;
			}
		} else {
			return new YanQuWSH0(webSocketURL, subprotocols, maxFramePayloadLength);
		}
	}



}
